{% extends "base.html" %}

{% block content %}
<div class="container mx-auto px-4 py-8">
    <div class="flex justify-between items-center mb-6">
        <h1 class="text-2xl font-bold" id="flowTitle">流程编辑器</h1>
        <div>
            <button onclick="saveFlow()" class="bg-blue-500 text-white px-4 py-2 rounded hover:bg-blue-600 mr-2">
                保存
            </button>
            <button onclick="window.location.href='/flows'" class="bg-gray-500 text-white px-4 py-2 rounded hover:bg-gray-600">
                返回列表
            </button>
        </div>
    </div>

    <div class="flex h-[800px]">
        <!-- 左侧组件列表 -->
        <div class="w-64 bg-white border rounded-lg p-4 mr-4">
            <h2 class="text-lg font-semibold mb-4">可用组件</h2>
            <div id="componentList" class="space-y-4">
                <!-- 组件列表将通过JavaScript动态加载 -->
            </div>
        </div>

        <!-- 右侧流程编辑区 -->
        <div class="flex-1 bg-white border rounded-lg">
            <div id="reactflow" class="w-full h-full"></div>
        </div>
    </div>
</div>

<!-- 组件配置模态框 -->
<div id="configModal" class="fixed inset-0 bg-gray-600 bg-opacity-50 hidden">
    <div class="relative top-20 mx-auto p-5 border w-96 shadow-lg rounded-md bg-white">
        <div class="mt-3">
            <h3 class="text-lg font-medium text-gray-900">组件配置</h3>
            <div class="mt-2">
                <div class="mb-4">
                    <label class="block text-sm font-medium text-gray-700">组件名称</label>
                    <input type="text" id="componentName" class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500">
                </div>
                <div class="mb-4">
                    <label class="block text-sm font-medium text-gray-700">系统提示词</label>
                    <textarea id="systemPrompt" class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500"></textarea>
                </div>
                <div class="mb-4">
                    <label class="block text-sm font-medium text-gray-700">用户提示词</label>
                    <textarea id="userPrompt" class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500"></textarea>
                </div>
                <div class="mb-4">
                    <label class="block text-sm font-medium text-gray-700">模型名称</label>
                    <input type="text" id="modelName" class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500">
                </div>
            </div>
            <div class="mt-4 flex justify-end">
                <button onclick="closeConfigModal()" class="px-4 py-2 bg-gray-200 text-gray-800 rounded hover:bg-gray-300 mr-2">
                    取消
                </button>
                <button onclick="saveComponentConfig()" class="px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600">
                    保存
                </button>
            </div>
        </div>
    </div>
</div>

<!-- 引入React Flow的样式 -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@reactflow/core@11.7.0/dist/style.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@reactflow/node-resizer@1.0.0/dist/style.css">

<!-- 引入React Flow的依赖 -->
<script src="https://cdn.jsdelivr.net/npm/react@18/umd/react.production.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/react-dom@18/umd/react-dom.production.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@reactflow/core@11.7.0/dist/umd/reactflow.production.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@reactflow/node-resizer@1.0.0/dist/umd/node-resizer.production.min.js"></script>
<!-- 引入Babel用于支持JSX -->
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>

<script type="text/babel">
    // 从 window.ReactFlow 中解构出需要的组件
    const { ReactFlow, ReactFlowProvider } = window.ReactFlow;
  
    // 定义FlowEditor组件
    function FlowEditor() {
        const [elements, setElements] = React.useState([]);
        const [flowName, setFlowName] = React.useState('');
        const reactFlowInstance = React.useRef(null);
  
        React.useEffect(() => {
            async function loadFlow() {
                try {
                    const response = await fetch(`/api/flows/${flowId}`);
                    const flow = await response.json();
  
                    setFlowName(flow.name);
  
                    const newElements = [
                        ...flow.components.map(component => ({
                            id: component.id,
                            type: 'default',
                            position: component.position,
                            data: {
                                label: component.name,
                                config: component.config
                            }
                        })),
                        ...flow.connections.map(connection => ({
                            id: `e${connection.source}-${connection.target}`,
                            source: connection.source,
                            target: connection.target,
                            sourceHandle: connection.sourceHandle,
                            targetHandle: connection.targetHandle
                        }))
                    ];
  
                    setElements(newElements);
                } catch (error) {
                    console.error('Error loading flow:', error);
                }
            }
  
            loadFlow();
        }, []);
  
        const onLoad = React.useCallback((_reactFlowInstance) => {
            reactFlowInstance.current = _reactFlowInstance;
            window.reactFlowInstance = _reactFlowInstance;
        }, []);
  
        const onNodesChange = React.useCallback((changes) => {
            // 处理节点变化
        }, []);
  
        const onEdgesChange = React.useCallback((changes) => {
            // 处理边变化
        }, []);
  
        const onConnect = React.useCallback((connection) => {
            // 处理连接
        }, []);
  
        const onNodeClick = React.useCallback((event, node) => {
            showConfigModal(node);
        }, []);
  
        return React.createElement('div', { style: { width: '100%', height: '100%' } },
            React.createElement('h1', { className: 'text-2xl font-bold mb-6' }, '流程编辑器 - ', flowName),
            React.createElement(ReactFlow, {
                elements: elements,
                onLoad: onLoad,
                onNodesChange: onNodesChange,
                onEdgesChange: onEdgesChange,
                onConnect: onConnect,
                onNodeClick: onNodeClick,
                style: { width: '100%', height: '800px' }
            })
        );
    }
  
    // 渲染FlowEditor组件，并使用ReactFlowProvider包裹
    const root = document.getElementById('reactflow');
    if (root) {
        ReactDOM.render(
            React.createElement(ReactFlowProvider, null, React.createElement(FlowEditor)),
            root
        );
    }
  
    // 拖拽和模态框相关函数（保持不变）
    function dragStart(event) {
        const type = event.target.dataset.type;
        const name = event.target.dataset.name;
        const config = JSON.parse(event.target.dataset.config);
        event.dataTransfer.setData('application/reactflow', JSON.stringify({ type, name, config }));
        event.dataTransfer.effectAllowed = 'move';
    }
  
    let currentNode = null;
  
    function showConfigModal(node) {
        currentNode = node;
        document.getElementById('componentName').value = node.data.label;
        document.getElementById('systemPrompt').value = node.data.config.system_prompt;
        document.getElementById('userPrompt').value = node.data.config.user_prompt;
        document.getElementById('modelName').value = node.data.config.model_name;
        document.getElementById('configModal').classList.remove('hidden');
    }
  
    function closeConfigModal() {
        document.getElementById('configModal').classList.add('hidden');
        currentNode = null;
    }
  
    function saveComponentConfig() {
        if (currentNode) {
            currentNode.data.label = document.getElementById('componentName').value;
            currentNode.data.config = {
                system_prompt: document.getElementById('systemPrompt').value,
                user_prompt: document.getElementById('userPrompt').value,
                model_name: document.getElementById('modelName').value
            };
            const elements = window.reactFlowInstance.getElements();
            window.reactFlowInstance.setElements(elements);
            closeConfigModal();
        }
    }
  
    async function saveFlow() {
        const elements = window.reactFlowInstance.getElements();
        const components = elements
            .filter(el => el.type === 'default')
            .map(node => ({
                id: node.id,
                type: 'llm',
                name: node.data.label,
                config: node.data.config,
                position: node.position
            }));
  
        const connections = elements
            .filter(el => el.type === 'edge')
            .map(edge => ({
                source: edge.source,
                target: edge.target,
                sourceHandle: edge.sourceHandle,
                targetHandle: edge.targetHandle
            }));
  
        try {
            const response = await fetch(`/api/flows/${flowId}`, {
                method: 'PUT',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({
                    components,
                    connections
                })
            });
  
            if (response.ok) {
                alert('保存成功');
            }
        } catch (error) {
            console.error('Error saving flow:', error);
        }
    }

    // 组件图标映射
    const componentIcons = {
        "llm": {
            "ollama": "M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z",
            "openai": "M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"
        },
        "vector_db": {
            "chroma": "M4 7v10c0 2.21 3.582 4 8 4s8-1.79 8-4V7M4 7c0 2.21 3.582 4 8 4s8-1.79 8-4M4 7c0-2.21 3.582-4 8-4s8 1.79 8 4"
        },
        "custom": {
            "python": "M10 20l4-16m4 4l4 4-4 4M6 16l-4-4 4-4"
        }
    };

    // 组件颜色映射
    const componentColors = {
        "llm": "text-blue-500",
        "vector_db": "text-purple-500",
        "custom": "text-yellow-500"
    };

    // 加载组件列表
    async function loadComponents() {
        try {
            const response = await fetch('/api/components');
            const components = await response.json();
            
            // 按类型分组
            const groupedComponents = components.reduce((acc, component) => {
                const type = component.type;
                if (!acc[type]) {
                    acc[type] = [];
                }
                acc[type].push(component);
                return acc;
            }, {});
            
            // 渲染组件列表
            const componentList = document.getElementById('componentList');
            componentList.innerHTML = Object.entries(groupedComponents)
                .map(([type, typeComponents]) => `
                    <div>
                        <h3 class="text-sm font-medium text-gray-500 mb-2">${type}</h3>
                        <div class="space-y-2">
                            ${typeComponents.map(component => `
                                <div class="p-2 border rounded cursor-move hover:bg-gray-50" 
                                     draggable="true"
                                     data-type="${component.type}"
                                     data-subtype="${component.subtype}"
                                     data-name="${component.name}"
                                     data-config='${JSON.stringify(component.config_schema)}'
                                     ondragstart="dragStart(event)">
                                    <div class="flex items-center">
                                        <svg class="w-4 h-4 mr-2 ${componentColors[type]}" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                                            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="${componentIcons[type]?.[component.subtype] || componentIcons[type]?.default || ''}" />
                                        </svg>
                                        ${component.name}
                                    </div>
                                </div>
                            `).join('')}
                        </div>
                    </div>
                `).join('');
        } catch (error) {
            console.error('Error loading components:', error);
        }
    }

    // 页面加载完成后加载组件列表
    document.addEventListener('DOMContentLoaded', loadComponents);
</script>
{% endblock %} 